package org.deltaset.samples.library.domain;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.annotation.ManagedBean;
import org.deltaset.meta.annotation.DsDefaultFinder;
import org.deltaset.meta.annotation.DsFirstResult;
import org.deltaset.meta.annotation.DsLabel;
import org.deltaset.meta.annotation.DsMaxResult;
import org.springframework.transaction.annotation.Transactional;

/**
 *
 * @author dmakariev
 */
@ManagedBean
public class AnimalRepositoryImpl extends AbstractAnimalRepository implements AnimalRepository {

    @Transactional
    @Override
    public void delete(Animal animal) {
        final Object forDelete = getEntityManager().getReference(Animal.class, animal.getId());
        getEntityManager().remove(forDelete);
    }

    @Transactional
    @Override
    public void save(Animal entity) {
        getEntityManager().merge(entity);
    }

    @Override
    public Animal findById(String id) {
        final Animal entity = getEntityManager().find(Animal.class, id);
        if (null == entity) {
            throw new IllegalArgumentException("Animal with id=" + id + " not found");
        }
        return entity;
    }

    @Override
    public Long countAll() {
        return getEntityManager().createQuery("SELECT count(*) from " + Animal.class.getName() + " o", Long.class).
                getSingleResult();
    }

    @Override
    @Transactional
    @DsDefaultFinder
    public List<Animal> findAll(@DsFirstResult Integer firstResult, @DsMaxResult Integer maxResult) {
        final List<Animal> founded = getEntityManager().createQuery("FROM " + Animal.class.getName() + " o ORDER BY o.name").
                setFirstResult(firstResult).
                setMaxResults(maxResult).getResultList();
        return new ArrayList<Animal>(founded);
    }

    @Transactional
    public List<Animal> findByName(@DsFirstResult Integer firstResult, @DsMaxResult Integer maxResult, @DsLabel("named") String name) {
        final List<Animal> founded = getEntityManager().createQuery("FROM " + Animal.class.getName() + " o WHERE o.name LIKE :name ORDER BY o.name").
                setParameter("name", "%" + name + "%").
                setFirstResult(firstResult).
                setMaxResults(maxResult).getResultList();
        return new ArrayList<Animal>(founded);
    }

    @Transactional
    public List<Animal> findAllList() {
        final List<Animal> founded = getEntityManager().createQuery("FROM " + Animal.class.getName() + " o ORDER BY o.name").
                getResultList();
        return new ArrayList<Animal>(founded);
    }

    @Override
    public Animal edit(Animal entity) {
        return entity;
    }

    public String action(String name, @DsLabel("the_person") Person person, Integer age, Date date, NameTitle nameTitle) {
        return "Hi name=" + name + " !";
    }

    public String action(ActionParameter actionParameter) {
        return "Hi ActionParameter name=" + actionParameter.getName() + " !";
    }

    public static class ActionParameter {

        private String name;
        @DsLabel("in_class_person")
        private Person person;
        private Integer age;
        private Date date;
        private NameTitle nameTitle;

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public Person getPerson() {
            return person;
        }

        public void setPerson(Person person) {
            this.person = person;
        }

        public Integer getAge() {
            return age;
        }

        public void setAge(Integer age) {
            this.age = age;
        }

        public Date getDate() {
            return date;
        }

        public void setDate(Date date) {
            this.date = date;
        }

        public NameTitle getNameTitle() {
            return nameTitle;
        }

        public void setNameTitle(NameTitle nameTitle) {
            this.nameTitle = nameTitle;
        }
    }
}
